<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    body{
      margin: 0;
    }
    input{
      position: fixed;
      z-index: 999;
    }
  </style>
  <script src="http://d3js.org/d3.v7.min.js"></script>
</head>
<body>
  <input type="button" value="添加">
  <div style="background-color: #f0f0f0; overflow: hidden; height: 100vh; width: 100vw;">
    <svg id="mainsvg" class="svgs" height="9000" width="2528"></svg>
  </div>
</body>
<script>
  
  // 数据
  let data = {
    name: "中国",
    children: [
      {
        name: "浙江",
        children: [
          {
            name: "浙江",
          },
          {
            name: "浙江",
            children: [
              {
                name: "浙江",
              },
              {
                name: "浙江",
              },
              {
                name: "浙江",
              },
              {
                name: "浙江",
                children: [
                  {
                    name: "浙江",
                  },
                  {
                    name: "浙江",
                  },
                  {
                    name: "浙江",
                  },
                  {
                    name: "浙江",
                    children: [
                      {
                        name: "浙江",
                      },
                      {
                        name: "浙江",
                      },
                      {
                        name: "浙江",
                      },
                      {
                        name: "浙江",
                        children: [
                          {
                            name: "浙江",
                          },
                          {
                            name: "浙江",
                          },
                          {
                            name: "浙江",
                          },
                          {
                            name: "浙江",
                          },
                        ]
                      },
                    ]
                  },
                  
                ]
              },
            ]
          },
          {
            name: "浙江",
            children: [
              {
                name: "浙江",
              },
              {
                name: "浙江",
              },
              {
                name: "浙江",
              },
              {
                name: "浙江",
              },
              {
                name: "浙江",
              },
              {
                name: "浙江",
              },
            ]
          },
        ]
      },
      {
        name: "浙江",
      },
    ]
  };

  // 定义矩形的宽高，折线据此确定横纵坐标
  var boxWidth = 170, boxHeight = 100;
  
  // 设置线条样式
  function elbow(d) {
    let sourceX = d.source.x,
      sourceY = d.source.y + boxHeight,
      targetX = d.target.x,
      targetY = d.target.y;

    return "M" + sourceX + "," + sourceY +
      "V" + ((targetY - sourceY) / 5 + sourceY) +
      "H" + targetX +
      "V" + targetY;
  }

  // 画线
  const render = function() {

    // 获取svg
    const svg = d3.select('#mainsvg')

    // 移除
    d3.selectAll('#maing').remove()
    
    const width = +svg.attr('width')
    const height = +svg.attr('height')
    const margin = {top: 100, right: 50, bottom: 100, left: 50}
    const innerWidth = width - margin.left - margin.right
    const innerHeight = height - margin.top - margin.bottom
    const g = svg.append('g').attr('id', 'maing')
    // .attr('width', width)
    // .attr('height', height)
    .attr('transform', `translate(${width / 2}, ${margin.top})`)
    
    
    // 放大缩小
    d3.select('div').call(d3.zoom().on("zoom", function (e) {
      // e.preventDefault()
      g.attr("transform", e.transform)
    }))

    // let gw = d3.select('#maing').attr('width')
    // let gh = d3.select('#maing').attr('height')
    // console.dir(document.querySelector('#maing'));
    let svgWidth = svg.attr('width')
    svg.attr('width', Number(svgWidth)+300)
    let svgHeight = svg.attr('width')
    svg.attr('heifht', Number(svgHeight)+100)
    
    let root = d3.hierarchy(data) // 预处理处理数据的接口
    // 预处理获取xy的坐标
    root = d3.tree()
    .nodeSize([200, 200])
    (root)

    // 添加组
    g.selectAll('.link').data(root.links()).join('g')
    .attr('class', 'link')
    // 线条
    .append('path')
    .attr('class', 'path')
    .attr('fill', 'none')
    .attr('stroke-width', '.2em')
    .attr('stroke', (d, i) => {
      if (i == 0){
        return '#F17A00'
      }else{
        return '#018903'
      }
    })
    .attr('d', elbow)


    // 矩形
    g.selectAll('.node').data(root.descendants()).join('rect')
    .attr('class', 'node')
    .attr('x', d => d.x - 85)
    .attr('y', d => d.y)
    .attr('width', 170)
    .attr('height', 100)
    .attr('rx', 4)
    .attr('ry', 4)
    .attr('fill', d => {
      if (d.data.name == '中国'){
        return 'none'
      }else{
        return '#fff'
      }
    })

    // 添加图像
    g.selectAll('.img').data(root.descendants()).join('image')
    .attr('href', d => {
      if(d.data.name == '中国'){
        return 'https://noc.ruijie.com.cn/macc5/img/network.bbdf5e66.png'
      } else {
        return 'https://noc.ruijie.com.cn/macc5/img/GW.cc09734c.svg'
      }
    })
    .attr('class', 'img')
    .attr('x', d => {
      if (d.data.name == '中国'){
        return d.x - 35
      }else{
        return d.x - 75
      }
    })
    .attr('y', d => {
      if (d.data.name == '中国'){
        return d.y + 40
      }else{
        return d.y + 25
      }
    })
    .attr('text-anchor', 'middle')
    .attr('width', d => {
      if (d.data.name == '中国'){
        return 70
      }else {
        return 150
      }
    })
    .attr('color', 'red')
  }

  document.querySelector('input').addEventListener('click', () => {
    // data.children.unshift({ name: "杭州giao", value: 100 })
    render()
    // 执行两次可以算出宽度
    // render()
  })
  
  
</script>
</html>